package cn.itcast.nems.studentrecord.service.impl;

import cn.itcast.nems.order.dto.OrderMode;
import cn.itcast.nems.studentrecord.constant.OrderSourceEnum;
import cn.itcast.nems.studentrecord.constant.ReferenceTypeEnum;
import cn.itcast.nems.studentrecord.converter.StudentRecordJournalConverter;
import cn.itcast.nems.studentrecord.converter.StudentRecordReceivableConverter;
import cn.itcast.nems.studentrecord.converter.StudentRecordReferenceConverter;
import cn.itcast.nems.studentrecord.dao.entity.StudentRecord;
import cn.itcast.nems.studentrecord.dao.entity.StudentRecordTransaction;
import cn.itcast.nems.studentrecord.dto.change.StudentRecordChangeDTO;
import cn.itcast.nems.studentrecord.dto.change.StudentRecordChangeResultDTO;
import cn.itcast.nems.studentrecord.dto.change.StudentRecordJournalDTO;
import cn.itcast.nems.studentrecord.dto.studentrecord.StudentRecordOrderCreateResultDTO;
import cn.itcast.nems.studentrecord.dto.studentrecord.StudentRecordReceivableCreateDTO;
import cn.itcast.nems.studentrecord.dto.studentrecord.StudentRecordReferenceDTO;
import cn.itcast.nems.studentrecord.service.studentrecord.*;

/**
 * 目标学籍带有订单的学籍变更超类
 *
 * @author liyong
 * create: 2023-12-11 19:56:22
 **/
abstract class StudentRecordChangeTargetWithOrder extends StudentRecordChangeServiceImpl {
    private final OrderApiDelegate orderApiDelegate;

    StudentRecordChangeTargetWithOrder(StudentRecordService studentRecordService,
                                       StudentRecordTransactionService studentRecordTransactionService,
                                       StudentRecordCreateService studentRecordCreateService,
                                       StudentRecordMessageService studentRecordMessageService,
                                       StudentRecordReceivableService studentRecordReceivableService,
                                       OrderApiDelegate orderApiDelegate) {
        super(studentRecordService,
                studentRecordCreateService,
                studentRecordTransactionService,
                studentRecordMessageService,
                studentRecordReceivableService,
                orderApiDelegate.getOrderApi());
        this.orderApiDelegate = orderApiDelegate;
    }

    StudentRecordChangeResultDTO change(StudentRecordChangeDTO studentRecordChange,
                                        ReferenceTypeEnum referenceType) {
        super.checkChange(studentRecordChange, checker -> checker.setIgnoredLock(true));
        String bizOrderNo = studentRecordChange.getJournalLineId();
        final OrderMode order = this.orderApiDelegate.findByBizOrderNo(bizOrderNo);
        if (order != null) {
            logger.warn("{}凭单行关联的订单已经存在: 学籍: '{}' 凭单行: '{}'", referenceType.getName(), studentRecordChange.getOriginStudentRecordId(), bizOrderNo);
            return null;
        }
        logger.info("{}创建目标班对应的订单, bizOrderNo(凭单行ID): {}", referenceType.getName(), bizOrderNo);
        OrderSourceEnum orderSource = OrderSourceEnum.valueOf(referenceType.name());
        final StudentRecordOrderCreateResultDTO orderResult = this.orderApiDelegate.createOrder(studentRecordChange, orderSource, bizOrderNo);
        logger.info("{}创建目标班对应的订单结果: {}", referenceType.getName(), orderResult);
        String orderId = orderResult.getOrderResultDTO().getOrderId();
        try {
            logger.info("{}创建目标班对应的学籍: 订单ID:{}, 凭单信息:{}", referenceType.getName(), orderId, studentRecordChange);
            StudentRecord studentRecord = super.createTargetStudentRecord(studentRecordChange, orderId, true);
            final StudentRecordReceivableCreateDTO dto = StudentRecordReceivableConverter.createDTO(studentRecord.getId(), orderResult);
            logger.info("{}创建目标班学籍应收:{}", referenceType.getName(), dto);
            super.addStudentRecordReceivable(dto);
            boolean complete = false;
            StudentRecordJournalDTO journalDTO = null;
            if (studentRecord.getActualAmountDue() <= 0) {
                complete = true;
                journalDTO = StudentRecordJournalConverter.createStudentRecordJournalDTO(studentRecordChange, orderResult.getOrderResultDTO());
                journalDTO.setTargetStudentRecordId(studentRecord.getId());
                logger.info("{}对应的目标班学籍实际应收为0，流程直接结束: {}", referenceType.getName(), journalDTO);
                // this.changeComplete(journalDTO, referenceType);
            }
            return new StudentRecordChangeResultDTO(complete, journalDTO, studentRecord.getId(), orderId);
        } catch (Exception e) {
            logger.warn(e.getMessage(), e);
            this.orderApiDelegate.cancel(orderId);
            throw e;
        }
    }

    void changeComplete(StudentRecordJournalDTO studentRecordJournal, ReferenceTypeEnum referenceType) {
        StudentRecord sr = this.studentRecordService.getById(studentRecordJournal.getTargetStudentRecordId());
        logger.info("{}完成，修改目标班学籍状态，学籍ID: '{}'", referenceType.getName(), sr.getId());
        super.studentRecordChangeComplete(sr, studentRecordJournal.getTargetClazzInDate());
        // super.popOrderIfExsit(sr.getId(), studentRecordJournal);
        StudentRecordReferenceDTO dto = StudentRecordReferenceConverter.target(sr, studentRecordJournal);
        logger.info("{}完成，创建目标班学籍流转记录，学籍ID: '{}' {}", referenceType.getName(), sr.getId(), dto);
        super.createStudentRecordTransaction(dto, null, StudentRecordTransaction.TYPE_IN);
    }
}
